/**
 * 引入内容
 */
import axios, { AxiosResponse, AxiosError } from 'axios';
// @ts-ignore
import { v4 } from 'uuid';
import { Message, Modal } from '@arco-design/web-vue';
import storage from '@/utils/storage';
import { refreshTokenMethod } from '@/api/login';
import router from '@/router';

// // 数据返回的接口
// // 定义请求响应参数，不含data
// interface Result {
//   code: number;
//   message: string;
//   success: string;
//   timestamp: number;
//   result: any;
// }

// /**
//  * 定义请求约束
//  */
// interface RequestRule {
//   needToken: boolean;
// }

/**
 * 请求头部
 */
interface requestHeaderRule {
  uuid?: null | string | number;
  accessToken?: string;
  token?: string;
}

// 清空并重新登录
function cleanStorage() {
  storage.setAccessToken('');
  // storage.setRefreshToken('');
  storage.setUuid('');
  router.push({
    path: '/login',
    query: {
      redirect: '',
    },
  });
}

/**
 * 设置公有的api
 */
export const commonUrl: string =
  process.env.NODE_ENV === 'development'
    ? ENV.BASE.API_DEV.gateway
    : ENV.BASE.API_PROD.gateway;
export const gatewayUrl: string =
  (process.env.NODE_ENV === 'development'
    ? ENV.BASE.API_DEV.gateway
    : ENV.BASE.API_PROD.gateway) + ENV.BASE.PREFIX;

/**
 * 请求失败后的错误统一处理
 */
const errorTips = (status: number, msg: string) => {
  // 状态码判断
  switch (status) {
    case 302:
      Message.error('接口重定向了！');
      break;
    case 400:
      Message.error(msg);
      break;
    case 401: // 重定向
      Message.error(`token:登录失效 ==>${status}:`);
      break;
    // 403 token过期
    // 清除token并跳转登录页
    case 403:
      Message.error(msg);
      break;
    case 404:
      Message.error(`网络请求不存在 ==> ${status}`);
      break;
    case 406:
      Message.error(`请求的格式不可得 ==> ${status}`);
      break;
    case 408:
      Message.error('请求超时！');
      break;
    case 410:
      Message.error(`请求的资源被永久删除，且不会再得到的==>${status}`);
      break;
    case 422:
      Message.error(`当创建一个对象时，发生一个验证错误==>${status}`);
      break;
    case 500:
      Message.error(msg);
      break;
    case 502:
      Message.error(`网关错误 ==>${status}`);
      break;
    case 503:
      Message.error(`服务不可用，服务器暂时过载或维护 ==>${status}`);
      break;
    case 504:
      Message.error(`网关超时 ==>${status}`);
      break;
    default:
      Message.error(msg);
  }
};

/**
 * 刷新token
 */

let isRefreshing = false;
// 重试队列
let requests: any = [];

/**
 * 创建axios
 */
const service = axios.create({
  timeout: ENV.TIMEOUT, // 请求超时时间
  baseURL: gatewayUrl, // API
});

// request拦截器
service.interceptors.request.use(
  (config: any) => {
    // 删除空参数
    if (config.params) {
      // eslint-disable-next-line no-restricted-syntax
      for (const [key, value] of Object.entries(config.params)) {
        if (value === undefined || value === null || value === '') {
          delete config.params[key];
        }
      }
    }
    if (config.data) {
      // eslint-disable-next-line no-restricted-syntax
      for (const [key, value] of Object.entries(config.data)) {
        if (value === undefined || value === null || value === '') {
          delete config.data[key];
        }
      }
    }

    let uuid = storage.getUuid();
    if (!uuid) {
      uuid = v4();
      storage.setUuid(uuid);
    }

    const requestHeader: requestHeaderRule = {
      uuid,
    };

    // 获取访问Token
    const accessToken = storage.getAccessToken();
    if (accessToken && config?.needToken) {
      requestHeader.token = accessToken;
    }
    config.headers = { ...config.headers, ...requestHeader };
    return config;
  },
  (error: AxiosError) => {
    Promise.reject(error);
  }
);

/**
 * response 拦截器
 * 状态码正常 返回接口数据
 * 状态码异常 返回接口数据 + 头部信息
 */
service.interceptors.response.use(
  async (response: AxiosResponse) => {
    const code: number = response.status;
    if (code === 200 && response.data.success) {
      return response;
    }

    let result = {};
    // 判断返回类型是否为blob类型
    if (toString.call(response.data) === '[object Blob]') {
      result = response.data;
    } else {
      result = { ...response.data, ...response.headers };
    }
    return result;
  },
  async (error) => {
    const { response } = error;
    // const token: any = storage.getAccessToken();

    if (response.status === 403) {
      Modal.info({
        title: '提示',
        content: '当前用户无权限访问该页面，请切换账号或联系管理员！',
        okText: '切换账号',
        cancelText: '确定',
        hideCancel: false,
        closable: false,
        onOk: () => {
          cleanStorage();
        },
      });
      router.push({
        path: '/workplace',
        query: {
          redirect: '',
        },
      });
      return;
    }

    if (response.data.code === 401) {
      Modal.warning({
        title: '系统提示',
        content: '登录状态已过期，请重新登录',
        hideCancel: true,
        maskClosable: false,
        closable: false,
        onOk: () => {
          cleanStorage();
        },
      });
    } // 如果当前返回没登录
    else if (response.data.code === 20004 || response.data.code === 20003) {
      cleanStorage();
    } else if (
      (response.status == 200 && !response.data.success) ||
      response.status == 400
    ) {
      if (response.data.message) {
        errorTips(0, response.data.message);
      }
    }
  }
);

export const Method = {
  GET: 'get',
  POST: 'post',
  PUT: 'put',
  DELETE: 'delete',
};

/**
 * 抛出request
 * @param options
 * @returns
 */
export default function request(options: object): Promise<AxiosResponse> {
  return service(options);
}
